package org.metasketch.editor.links;

import groovy.lang.Binding;
import groovy.lang.GroovyShell;

import org.metasketch.editor.toolbox.ISemanticFactory;
import org.metasketch.editor.toolbox.advanced.ISemanticTypeTester;
import org.metasketch.model.CommonIdentified;

public class SemanticConfig implements ISemanticTypeTester {

	Class semanticType;
	ISemanticFactory semanticFactory;
	String semanticBuildScript;

	String sourceFieldname;
	String semanticSourceFieldname;

	String targetFieldname;
	String semanticTargetFieldname;

	String linkSourceFieldname;
	String linkSemanticSourceFieldname;

	String linkTargetFieldname;
	String linkSemanticTargetFieldname;

	String semanticSetupScript;

	String semanticTestScript;

	public Class getSemanticType() {
		return semanticType;
	}

	public void setSemanticType(Class semanticType) {
		this.semanticType = semanticType;
	}

	public String getSourceFieldname() {
		return sourceFieldname;
	}

	public void setSourceFieldname(String sourceFieldname) {
		this.sourceFieldname = sourceFieldname;
	}

	public String getTargetFieldname() {
		return targetFieldname;
	}

	public void setTargetFieldname(String targetFieldname) {
		this.targetFieldname = targetFieldname;
	}

	public String getLinkSourceFieldname() {
		return linkSourceFieldname;
	}

	public void setLinkSourceFieldname(String linkSourceFieldname) {
		this.linkSourceFieldname = linkSourceFieldname;
	}

	public String getLinkTargetFieldname() {
		return linkTargetFieldname;
	}

	public void setLinkTargetFieldname(String linktargetFieldname) {
		this.linkTargetFieldname = linktargetFieldname;
	}

	public String getSemanticSourceFieldname() {
		return semanticSourceFieldname;
	}

	public void setSemanticSourceFieldname(String semanticSourceFieldname) {
		this.semanticSourceFieldname = semanticSourceFieldname;
	}

	public String getSemanticTargetFieldname() {
		return semanticTargetFieldname;
	}

	public void setSemanticTargetFieldname(String targetSemanticSourceFieldname) {
		this.semanticTargetFieldname = targetSemanticSourceFieldname;
	}

	public String getLinkSemanticSourceFieldname() {
		return linkSemanticSourceFieldname;
	}

	public void setLinkSemanticSourceFieldname(
			String linkSemanticSourceFieldname) {
		this.linkSemanticSourceFieldname = linkSemanticSourceFieldname;
	}

	public String getLinkSemanticTargetFieldname() {
		return linkSemanticTargetFieldname;
	}

	public void setLinkSemanticTargetFieldname(String linkTargetSourceFieldname) {
		this.linkSemanticTargetFieldname = linkTargetSourceFieldname;
	}

	public String getSemanticSetupScript() {
		return semanticSetupScript;
	}

	public void setSemanticSetupScript(String script) {
		this.semanticSetupScript = script;
	}

	public CommonIdentified createNewInstance() throws InstantiationException,
			IllegalAccessException {
		CommonIdentified semantic = null;

		if (semanticFactory != null) {
			semantic = semanticFactory.getNewInstance();
		} else if (semanticType != null) {
			semantic = (CommonIdentified) semanticType.newInstance();
			// return semantic;
		}

		if (semanticBuildScript != null) {
			Binding binding = new Binding();
			binding.setVariable("semantic", semantic);
			binding.setVariable("type", semanticType);
			GroovyShell shell = new GroovyShell(binding);

			Object result = shell.evaluate(semanticBuildScript);

			if (semantic == null)
				semantic = (CommonIdentified) result;
		}

		return semantic;
	}

	public ISemanticFactory getSemanticFactory() {
		return semanticFactory;
	}

	public void setSemanticFactory(ISemanticFactory semanticFactory) {
		this.semanticFactory = semanticFactory;
	}

	public String getSemanticBuildScript() {
		return semanticBuildScript;
	}

	public void setSemanticBuildScript(String semanticBuildScript) {
		this.semanticBuildScript = semanticBuildScript;
	}

	public Class getProperSemanticType() {
		if (semanticFactory != null) {
			return semanticFactory.getSemanticType();
		}

		return semanticType;
	}

	public String getSemanticTestScript() {
		return semanticTestScript;
	}

	public void setSemanticTestScript(String semanticTestScript) {
		this.semanticTestScript = semanticTestScript;
	}

	@Override
	public boolean isValid(CommonIdentified semantic) {

		if (semanticTestScript == null)
			return getProperSemanticType() == semantic.getClass();

		if (getProperSemanticType() != semantic.getClass())
			return false;

		Binding binding = new Binding();
		binding.setVariable("semantic", semantic);
		binding.setVariable("type", semantic.getClass());
		GroovyShell shell = new GroovyShell(binding);

		boolean result = (Boolean) shell.evaluate(semanticTestScript);

		return result;

	}

}
